package fr.umlv.m2.jee.pmlv.web.student;

import fr.umlv.m2.jee.pmlv.persistence.cursus.SpecialtySubject;
import fr.umlv.m2.jee.pmlv.persistence.planning.EventCopyConsultation;
import fr.umlv.m2.jee.pmlv.persistence.planning.EventExam;
import fr.umlv.m2.jee.pmlv.persistence.planning.EventLesson;
import fr.umlv.m2.jee.pmlv.persistence.planning.EventTD;
import fr.umlv.m2.jee.pmlv.persistence.planning.EventTP;
import fr.umlv.m2.jee.pmlv.service.cursus.IDisplayCursusService;
import fr.umlv.m2.jee.pmlv.service.planning.DisplayAbstractEvent;
import fr.umlv.m2.jee.pmlv.service.planning.IDisplayAbstractEventService;
import fr.umlv.m2.jee.pmlv.service.user.User;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletContext;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * Servlet wich represents event's list of a students for a week.
 * @author Yuxi
 */
public class ScheduleOfCoursesAndExams extends HttpServlet {
    // Variables
    private User user = null;   //Contains informations about user
    private List<Integer> years = new ArrayList<Integer>(); 
    private int currentYear = -1;   //the current year
    private GregorianCalendar monday = null;    //First day of a week concerned
    private GregorianCalendar saturday = null;  //Last day of a week concerned
    private int incrWeek = 0;   //Week concerned
    private List<DisplayAbstractEvent> events = new ArrayList<DisplayAbstractEvent>();    //Events of week

    /**
     * @see HttpServlet#HttpServlet()
     */
    public ScheduleOfCoursesAndExams() {
            super();
    }

    /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response).
    */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        doPost(request,response);
    }

    /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response).
    */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        //Data
        user = null;
        years.clear();
        currentYear = -1;
        monday = null;
        saturday = null;
        incrWeek = 0;
        events.clear();

        //Retrieve informations about user
        HttpSession session = request.getSession(true);
        user = (User)session.getAttribute("user");
        years.addAll((List<Integer>)session.getAttribute("years"));
        if(Calendar.getInstance(Locale.FRENCH).get(Calendar.MONTH)>9) currentYear = Calendar.getInstance(Locale.FRENCH).get(Calendar.YEAR);
        else currentYear = Calendar.getInstance(Locale.FRENCH).get(Calendar.YEAR) - 1;

        //Retrieve first day and last of week concerned
        if(request.getParameter("week")!=null)
            incrWeek = Integer.parseInt(request.getParameter("week"));
        monday = new GregorianCalendar(Locale.FRENCH);
        monday.add(Calendar.WEEK_OF_YEAR, incrWeek); monday.add(Calendar.DAY_OF_WEEK, (Calendar.MONDAY - monday.get(Calendar.DAY_OF_WEEK)));
        saturday = new GregorianCalendar(monday.get(Calendar.YEAR),monday.get(Calendar.MONTH),monday.get(Calendar.DATE));
        saturday.add(Calendar.DAY_OF_WEEK, 5);

        //Retrieve event for week concerned
        ServletContext context = getServletContext();
        WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(context);
        IDisplayAbstractEventService eventService = (IDisplayAbstractEventService) applicationContext.getBean("defautDisplayAbstractEventService");
        IDisplayCursusService cursusService = (IDisplayCursusService) applicationContext.getBean("defautDisplayCursusService");
        if(request.getParameter("reserveProjo")!=null)
        {
            long id = Long.parseLong(request.getParameter("reserveProjo"));
            eventService.reserveProjector(id);
        }
        else if(request.getParameter("cancelProjo")!=null)
        {
            long id = Long.parseLong(request.getParameter("cancelProjo"));
            eventService.cancelProjector(id);
        }
        events.addAll(eventService.getAbstractEventByWeekAndByStudentUidAndByYear(monday, user.getuId(), currentYear));


        //View
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
        out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"fr\" >");

        out.println(" <head>");
        out.println("   <title>PMLV : Portail Universitaire de Marne-La-Vall&eacute;e</title>");
        out.println("   <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />");
        out.println("   <link rel=\"stylesheet\" media=\"screen\" type=\"text/css\" href=\"../css/student/student.css\" />");
        out.println("   <link rel=\"stylesheet\" media=\"screen\" type=\"text/css\" href=\"../css/professor/scheduleOfEvents.css\" />");
        out.println(" </head>");

        out.println(" <body>");

        out.println("   <div id=\"header\">");
        out.println("     <ul>");
        out.println("       <li class=\"menuItem menuItemSpacing\"><a href=\"../Student\">Accueil</a></li>");
        out.println("       <li class=\"menuItem menuItemSpacing\"><a href=\"Inscription\">Inscription</a></li>");
        out.println("       <li class=\"menuItem menuItemSpacing cursor\">Emploi du temps");
        out.println("         <ul class=\"subMenuBar\">");
        out.println("           <li class=\"subMenu\"><a href=\"ScheduleOfCoursesAndExams\">Cours et examens</a></li>");
        out.println("           <li class=\"subMenu\"><a href=\"ScheduleOfWorksToMake\">Rendu de travaux</a></li>");
        out.println("         </ul>");
        out.println("       </li>");
        out.println("       <li class=\"menuItem menuItemSpacing cursor\">Mati&egrave;res");
        out.println("         <ul class=\"subMenuBar\">");
        for(Integer year:years)
        {
            out.println("           <li class=\"subMenu\"><a href=\"Subjects?year="+year+"\">"+ year +"-"+ (year+1) +"</a></li>");
        }
        out.println("         </ul>");
        out.println("       </li>");
        out.println("       <li class=\"menuItem menuItemSpacing\"><a href=\"Result\">Avis de passage</a></li>");
        out.println("       <li id=\"menuItemMargin\" class=\"menuItem\"><a href=\"../j_spring_security_logout\">Se d&eacute;connecter</a></li>");
        out.println("     </ul>");
        out.println("   </div>");

        getDivContent(out, request, response);

        out.println("   <div id=\"footer\">");
        out.println("     <div id=\"copyright\">&copy; Universit&eacute; Paris-Est Marne-la-Vall&eacute;e</div>");
        out.println("     <div>PMLV v1.0 </div>");
        out.println("   </div>");

        out.println(" </body>");

        out.println("</html>");
        out.close();
    }

    /**
     *  Content of page
     */
    private void getDivContent(PrintWriter out, HttpServletRequest request, HttpServletResponse response)
    {
        String str_monday = monday.get(Calendar.DATE) +" "+monday.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.FRENCH);
        String str_saturday = saturday.get(Calendar.DATE) +" "+saturday.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.FRENCH);

        out.println("   <div id=\"content\">");
        out.println("     <div id=\"title\">Emploi du temps des cours et des examens</div>");

        out.println("       <table id=\"scheduleTable\">");
        out.println("         <caption>");
        out.println("           <a href=\"ScheduleOfCoursesAndExams?week="+(incrWeek-1)+"\">&lt;&lt;&nbsp;</a></div>");
        out.println("           Semaine du "+str_monday+" au "+str_saturday);
        out.println("           <a href=\"ScheduleOfCoursesAndExams?week="+(incrWeek+1)+"\">&nbsp;&gt;&gt;</a>");
        out.println("         </caption>");

        out.println("         <tr>");
        out.println("           <th colspan=\"4\" style=\"border-left: none; border-top: none;\"></th>");
        for(int i=8;i<19;i++)
        {
            out.println("          <th colspan=\"4\">"+i+"h00<br/>-<br/>"+(i+1)+"h00</th>");
        }
        out.println("         </tr>");


        GregorianCalendar tmp = new GregorianCalendar(monday.get(Calendar.YEAR), monday.get(Calendar.MONTH), monday.get(Calendar.DATE));
        String[] day = {"Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"};
        int elapsed_time = 8*4; int e=0; int d=0;
        while(d<6)
        {
            if(e>=events.size() && elapsed_time==8*4)
            {
                out.println("         <tr>");
                out.println("           <th colspan=\"4\">"+day[d]+"<br/>"+ tmp.get(Calendar.DATE) +" "+tmp.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.FRENCH) +"</th>");
                for(int j=0;j<(19*4)-(8*4);j++)
                {
                    if(j%4==0) out.println("           <td class=\"emptyLeft\"> &nbsp </td>");
                    else if(j%4==3) out.println("           <td class=\"emptyRight\"> &nbsp </td>");
                    else out.println("           <td class=\"empty\"> &nbsp </td>");
                }
                d++;
                tmp.add(Calendar.DAY_OF_WEEK, 1);
                out.println("         </tr>");
            }
            else if(e>=events.size())
            {
                int gap = (19*4) - elapsed_time;
                for(int j=elapsed_time;j<gap+elapsed_time;j++)
                {
                    if(j%4==0) out.println("           <td class=\"emptyLeft\"> &nbsp </td>");
                    else if(j%4==3) out.println("           <td class=\"emptyRight\"> &nbsp </td>");
                    else out.println("           <td class=\"empty\"> &nbsp </td>");
                }
                out.println("         </tr>");
                elapsed_time = 8*4;
                d++;
                tmp.add(Calendar.DAY_OF_WEEK, 1);
            }
            else
            {
                if(tmp.get(Calendar.DAY_OF_WEEK)-1!=events.get(e).getBegin().getDay() && elapsed_time==8*4)
                {
                    out.println("         <tr>");
                    out.println("           <th colspan=\"4\">"+day[d]+"<br/>"+ tmp.get(Calendar.DATE) +" "+tmp.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.FRENCH) +"</th>");
                    for(int j=0;j<(19*4)-(8*4);j++)
                    {
                        if(j%4==0) out.println("           <td class=\"emptyLeft\"> &nbsp </td>");
                        else if(j%4==3) out.println("           <td class=\"emptyRight\"> &nbsp </td>");
                        else out.println("           <td class=\"empty\"> &nbsp </td>");
                    }
                    d++;
                    tmp.add(Calendar.DAY_OF_WEEK, 1);
                    out.println("         </tr>");
                }
                else if(tmp.get(Calendar.DAY_OF_WEEK)-1!=events.get(e).getBegin().getDay())
                {
                    int gap = (19*4) - elapsed_time;
                    for(int j=elapsed_time;j<gap+elapsed_time;j++)
                    {
                        if(j%4==0) out.println("           <td class=\"emptyLeft\"> &nbsp </td>");
                        else if(j%4==3) out.println("           <td class=\"emptyRight\"> &nbsp </td>");
                        else out.println("           <td class=\"empty\"> &nbsp </td>");
                    }
                    out.println("         </tr>");
                    elapsed_time = 8*4;
                    d++;
                    tmp.add(Calendar.DAY_OF_WEEK, 1);
                }
                else
                {
                    if(elapsed_time==8*4)
                    {
                        out.println("         <tr>");
                        out.println("           <th colspan=\"4\">"+day[d]+"<br/>"+ tmp.get(Calendar.DATE) +" "+tmp.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.FRENCH) +"</th>");
                    }
                    int gap = (((events.get(e).getBegin().getHours()*60)+events.get(e).getBegin().getMinutes())/15) - elapsed_time;
                    int duration = ( ((events.get(e).getEnd().getHours()-events.get(e).getBegin().getHours())*60) + (events.get(e).getEnd().getMinutes()-events.get(e).getBegin().getMinutes()) )/15;
                    for(int j=elapsed_time;j<gap+elapsed_time;j++)
                    {
                        if(j%4==0) out.println("           <td class=\"emptyLeft\"> &nbsp </td>");
                        else if(j%4==3) out.println("           <td class=\"emptyRight\"> &nbsp </td>");
                        else out.println("           <td class=\"empty\"> &nbsp </td>");
                    }

                    out.println("           <td class=\"event\" colspan=\""+ duration +"\">");
                    String type = ""; String cursus = "";
                    for(SpecialtySubject spesub:events.get(e).getSubject().getSpecialtySubject())
                    {
                        cursus = spesub.getSpecialty().getCursus().getName();
                        break;
                    }
                    if(events.get(e).getAbstractEvent() instanceof EventTP) type=" TP ";
                    else if(events.get(e).getAbstractEvent() instanceof EventTD) type=" TD ";
                    out.println("               "+cursus+"<br/>"+type+""+events.get(e).getSubject().getAbbreviation()+"<br/> "+events.get(e).getClassroom().getNumber());
                    if( (events.get(e).getAbstractEvent() instanceof EventLesson) || (events.get(e).getAbstractEvent() instanceof EventTD) || (events.get(e).getAbstractEvent() instanceof EventTP) ) { }
                    else if(events.get(e).getAbstractEvent() instanceof EventCopyConsultation)
                        out.println("               <br/><u>Consultation de Copies</u>");
                    else if(events.get(e).getAbstractEvent() instanceof EventExam)
                        out.println("               <br/><u>Examen</u>");
                    out.println("           </td>");

                    elapsed_time = elapsed_time + duration + gap;
                    e++;
                }
            }
        }

        out.println("       </table>");
        out.println("   </div>");
    }
}
